﻿#region File Description
//-----------------------------------------------------------------------------
// AnimatedTexture.cs
//
// AnimatedTexture draws the sprite using the subrectangle of the texture that contains the desired animation.
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// Tutorial from: http://msdn.microsoft.com/en-us/library/bb203866.aspx
// for animating sprites
//
// Some edits and commenting by: Lizz Bartos
// Also used Animation.cs and AnimationPlayer.cs for reference from platformer starter kit
//
//-----------------------------------------------------------------------------
#endregion

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace _2DProject
{
    public class AnimatedTexture
    {
        
        private Texture2D spriteSheet;  // The sprite sheet (formerly called myTexture)
        public Vector2 Origin;          // Origin of the texture

        private int frameCount;         // Total number of frames in the animation loop
        private float timePerFrame;     // Duration of time to show each frame
        private int frameIndex;         // The current frame number/frame index (formerly Frame)
        private float timeShown;        // The amount of time (in seconds) that the current frame has been shown for (formerly TotalElapsed)
        
        private bool Paused;            // Whether or not the animation is currently paused

        private Rectangle sourceRect;   // Rectangle that highlights the appropriate sprite in the sprite sheet
        private int frameWidth;     // The width of the box that highlights the current sprite image in the sheet
        private int frameHeight;    // The height of the box that highlights the current sprite image in the sheet

        public float Rotation, Scale, Depth; // don't think we ever use these, for the extent of our game

      
        //--- Public getters/setters for member variables ---//

        public int spriteWidth
        {
            get { return frameWidth; }
            set { frameWidth = value; }
        }

        public int spriteHeight
        {
            get { return frameHeight; }
            set { frameHeight = value; }
        }



        ///
        /// AnimatedTexture Constructor
        ///
        public AnimatedTexture(Vector2 origin, float rotation, float scale, float depth)
        {
            this.Origin = origin;
            this.Rotation = rotation;
            this.Scale = scale;
            this.Depth = depth;
        }

        /*---------------------------------------------------------------------------
          Name:     AdjustSpriteFrame
          Purpose:  Allows the source frame for the current sprite to be adjusted
                    (by the Character class)
          Receives: the width and height for the sprite frame,
                    and the number of frames in the animation loop
          Returns:  void
        ---------------------------------------------------------------------------*/
        public void AdjustSpriteFrame(int width, int height, int numFrames)
        {
            frameWidth = width;
            frameHeight = height;
            frameCount = numFrames;
        }


        //
        // Load one or more textures to provide the image data for the animation.
        // Loads a single texture and divides it into frames of animation.
        // It uses the last parameter to determine how many frames to draw each second.
        //
        public void Load(ContentManager content, string asset, 
            int count, int framesPerSec)
        {
            frameCount = count;
            spriteSheet = content.Load<Texture2D>(asset);
            timePerFrame = (float)1 / 5;
            frameIndex = 0;
            timeShown = 0;
            Paused = false;

            // Defaults - make sure that frameWidth, frameHeight, and sourceRect
            // are initialized to reasonable values
            // May need to adjust per character --> use AdjustSpriteFrame from Character class
            frameWidth = spriteSheet.Width / frameCount;
            frameHeight = spriteSheet.Height / frameCount;
            sourceRect = new Rectangle(frameWidth * frameIndex, 0, frameWidth, frameHeight);
        }


        /// <summary>
        /// Determines which animation frame to display by taking the elapsed seconds between updates as a parameter.
        /// </summary>
        public void UpdateFrame(float elapsed)
        {
            if (Paused)
                return;

            // Process passing time.
            timeShown += elapsed;
            if (timeShown > timePerFrame)
            {
                frameIndex++;    // Increment to the next Frame number
                    // Keep the Frame between 0 and the total frames, minus one.
                    // i.e., if the sourceRect gets to the end of the sprite sheet,
                    // go back to the beginning of the sprite sheet
                frameIndex = frameIndex % frameCount;
                timeShown -= timePerFrame;
            }
        }

        /// <summary>
        /// DrawFrame - wrapper method to be called from Character Class
        /// </summary>
        public void DrawFrame(SpriteBatch batch, Vector2 screenPos, Boolean isFacingRight)
        {
            // Use the direction that the character is moving
            // to decide whether or not to horizontally flip the sprite
            // (sprite sheets depict characters facing right)
            SpriteEffects flip = SpriteEffects.FlipHorizontally;
            if (isFacingRight) flip = SpriteEffects.None;

            DrawFrame(batch, frameIndex, screenPos, flip);
        }

        //
        // DrawFrame - internal method that draws the correct frame of sprite animation
        //
        private void DrawFrame(SpriteBatch batch, int frame, Vector2 screenPos, SpriteEffects flip)
        {
            // Calculate the source rectangle of the current frame.
            sourceRect = new Rectangle(frameWidth * frame, 0, frameWidth, frameHeight);

            // Draw the current frame.
            batch.Draw(spriteSheet, screenPos, sourceRect, Color.White,
                Rotation, Origin, Scale, flip, Depth);
        }

        //
        //--- Functions to control the animation of the sprite ---//
        //

        public void Play() { Paused = false; }

        public void Pause() { Paused = true; }

        public bool IsPaused {  get { return Paused; }  }

        public void Stop()
        {
            Pause();
            Reset();
        }

        public void Reset()
        {
            frameIndex = 0;
            timeShown = 0f;
        }

    }
}